/*
 * MainScreen.java
 *
 * Created on 29 de Agosto de 2008, 10:10
 */

package gui;

import javax.swing.JOptionPane;
import javax.swing.JTextField;
import java.util.Vector;
import bean.Process;
import java.awt.Dimension;
import java.text.DecimalFormat;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import manager.Calculator;
import thread.AlgorithmStepsThread;

/**
 *
 * @author  Fabricio Reis
 */
public class MainScreen extends javax.swing.JApplet {
    
    // Definitions shown to the user when the applet starts
    final static String START_TEXT = "Seja bem vindo! \n Para começar a usar este software educativo clique em 'Introdução'.";
    final static int MINIMUM = 1; // This constant defines the minimum burst time allowed to create a process
    final static int MAXIMUM = 10; // This constant defines the maximum burst time allowed to create a process
    
    Vector<Process> processesList = new Vector<Process>(); //This object stores the processes created by the user
    
    int processCounter = 0; //This variable is used to label orderly the blocks in 'jPanelReadyProcesses'
    int timeCounter = 0; //This variable is used to implement a logical clock
    float waitingTimeNecessary = 0; //This variable is used control the process' waiting time necessary to be executed
    
    Vector<Process> reportBase = new Vector<Process>(); //This vector stores all the processes created with its values (waiting time, turn around).
                                                        //It is used to show a report to the user
    Vector<Process> reportBaseTemp = new Vector<Process>();

    Calculator calculator = new Calculator(); //See the class 'Calculator' for more details
    
    AlgorithmStepsThread st;
    Thread t;
    
    /** Initializes the applet MainScreen */    
    @Override
    public void init() {
        try {
            this.setSize(961, 642);
            JOptionPane.showMessageDialog(null, START_TEXT, "", JOptionPane.INFORMATION_MESSAGE);
            java.awt.EventQueue.invokeAndWait(new Runnable() {
                public void run() {
                    initComponents();
                    jPanelLegend.setVisible(false);
                    jPanelProcesses.setVisible(false);
                    jPanelReadyProcesses.setVisible(false);
                    jProgressBarExecution.setVisible(false);
                    jLabelTime.setVisible(false);
                    jLabelTimeCounter.setVisible(false);
                    jButtonOkNextStep.setVisible(false);
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }    
    
    /** This method is called from within the init() method to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanelIntroduction = new javax.swing.JPanel();
        jScrollPaneIntroduction = new javax.swing.JScrollPane();
        jTextAreaIntroduction = new javax.swing.JTextArea();
        jPanelAlgorithm = new javax.swing.JPanel();
        jScrollPaneAlgorithm = new javax.swing.JScrollPane();
        jTextAreaAlgorithm = new javax.swing.JTextArea();
        jPanelAnimation = new javax.swing.JPanel();
        jPanelCPU = new javax.swing.JPanel();
        jLabelCPU = new javax.swing.JLabel();
        jPanelReadyProcesses = new javax.swing.JPanel();
        jLabelIncreaseOrientation = new javax.swing.JLabel();
        jLabelTime = new javax.swing.JLabel();
        jLabelTimeCounter = new javax.swing.JLabel();
        jProgressBarExecution = new javax.swing.JProgressBar();
        jLabelShowBurstTime = new javax.swing.JLabel();
        jLabelShowCreationTime = new javax.swing.JLabel();
        jPanelLegend = new javax.swing.JPanel();
        jTextFieldLegendReady = new javax.swing.JTextField();
        jTextFieldLegendExecuting = new javax.swing.JTextField();
        jPanelProcesses = new javax.swing.JPanel();
        jLabelBurstTime = new javax.swing.JLabel();
        jTextFieldBurstTime = new javax.swing.JTextField();
        jButtonCreateProcess = new javax.swing.JButton();
        jButtonIntroduction = new javax.swing.JButton();
        jButtonStart = new javax.swing.JButton();
        jButtonAlgorithmSteps = new javax.swing.JButton();
        jButtonRestart = new javax.swing.JButton();
        jButtonReport = new javax.swing.JButton();
        jButtonOkNextStep = new javax.swing.JButton();

        setBackground(new java.awt.Color(204, 204, 204));

        jPanelIntroduction.setBorder(javax.swing.BorderFactory.createTitledBorder("Introdução"));

        jTextAreaIntroduction.setColumns(20);
        jTextAreaIntroduction.setEditable(false);
        jTextAreaIntroduction.setFont(new java.awt.Font("Tahoma", 1, 12));
        jTextAreaIntroduction.setRows(5);
        jTextAreaIntroduction.setToolTipText("Aqui será exibida uma breve introdução da política tratada");
        jScrollPaneIntroduction.setViewportView(jTextAreaIntroduction);

        javax.swing.GroupLayout jPanelIntroductionLayout = new javax.swing.GroupLayout(jPanelIntroduction);
        jPanelIntroduction.setLayout(jPanelIntroductionLayout);
        jPanelIntroductionLayout.setHorizontalGroup(
            jPanelIntroductionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPaneIntroduction, javax.swing.GroupLayout.DEFAULT_SIZE, 925, Short.MAX_VALUE)
        );
        jPanelIntroductionLayout.setVerticalGroup(
            jPanelIntroductionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPaneIntroduction, javax.swing.GroupLayout.DEFAULT_SIZE, 87, Short.MAX_VALUE)
        );

        jPanelAlgorithm.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Algoritmo", javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.TOP));

        jTextAreaAlgorithm.setColumns(20);
        jTextAreaAlgorithm.setEditable(false);
        jTextAreaAlgorithm.setFont(new java.awt.Font("Tahoma", 1, 12));
        jTextAreaAlgorithm.setRows(5);
        jTextAreaAlgorithm.setToolTipText("Aqui será exibido o algoritmo da política tratada");
        jScrollPaneAlgorithm.setViewportView(jTextAreaAlgorithm);

        javax.swing.GroupLayout jPanelAlgorithmLayout = new javax.swing.GroupLayout(jPanelAlgorithm);
        jPanelAlgorithm.setLayout(jPanelAlgorithmLayout);
        jPanelAlgorithmLayout.setHorizontalGroup(
            jPanelAlgorithmLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPaneAlgorithm, javax.swing.GroupLayout.DEFAULT_SIZE, 405, Short.MAX_VALUE)
        );
        jPanelAlgorithmLayout.setVerticalGroup(
            jPanelAlgorithmLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPaneAlgorithm, javax.swing.GroupLayout.DEFAULT_SIZE, 441, Short.MAX_VALUE)
        );

        jPanelAnimation.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Gerência de Processos", javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.TOP));
        jPanelAnimation.setToolTipText("Aqui serão exibidas animações gráficas da gerência de processos");
        jPanelAnimation.setPreferredSize(new java.awt.Dimension(474, 204));

        jPanelCPU.setBackground(new java.awt.Color(200, 233, 251));
        jPanelCPU.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 1, true));
        jPanelCPU.setToolTipText("UCP (Unidade Central de Processamento)");
        jPanelCPU.setPreferredSize(new java.awt.Dimension(98, 69));

        jLabelCPU.setFont(new java.awt.Font("Tahoma", 1, 12));
        jLabelCPU.setText("UCP");

        javax.swing.GroupLayout jPanelCPULayout = new javax.swing.GroupLayout(jPanelCPU);
        jPanelCPU.setLayout(jPanelCPULayout);
        jPanelCPULayout.setHorizontalGroup(
            jPanelCPULayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelCPULayout.createSequentialGroup()
                .addContainerGap(72, Short.MAX_VALUE)
                .addComponent(jLabelCPU))
        );
        jPanelCPULayout.setVerticalGroup(
            jPanelCPULayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelCPULayout.createSequentialGroup()
                .addContainerGap(52, Short.MAX_VALUE)
                .addComponent(jLabelCPU))
        );

        jPanelReadyProcesses.setBorder(javax.swing.BorderFactory.createTitledBorder("Processos Prontos"));
        jPanelReadyProcesses.setToolTipText("Processos Prontos");
        jPanelReadyProcesses.setPreferredSize(new java.awt.Dimension(267, 163));

        jLabelIncreaseOrientation.setText("--> +");

        javax.swing.GroupLayout jPanelReadyProcessesLayout = new javax.swing.GroupLayout(jPanelReadyProcesses);
        jPanelReadyProcesses.setLayout(jPanelReadyProcessesLayout);
        jPanelReadyProcessesLayout.setHorizontalGroup(
            jPanelReadyProcessesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelReadyProcessesLayout.createSequentialGroup()
                .addComponent(jLabelIncreaseOrientation)
                .addContainerGap(224, Short.MAX_VALUE))
        );
        jPanelReadyProcessesLayout.setVerticalGroup(
            jPanelReadyProcessesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelReadyProcessesLayout.createSequentialGroup()
                .addComponent(jLabelIncreaseOrientation)
                .addContainerGap(119, Short.MAX_VALUE))
        );

        jLabelTime.setFont(new java.awt.Font("Tahoma", 1, 12));
        jLabelTime.setText("Tempo:");
        jLabelTime.setToolTipText("Relógio lógico do tempo de processamento");

        jLabelTimeCounter.setFont(new java.awt.Font("Tahoma", 1, 12));
        jLabelTimeCounter.setText("0");
        jLabelTimeCounter.setToolTipText("Relógio lógico do tempo de processamento");

        jProgressBarExecution.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        jProgressBarExecution.setStringPainted(true);

        jLabelShowBurstTime.setFont(new java.awt.Font("Tahoma", 1, 12));
        jLabelShowBurstTime.setText(" ");

        jLabelShowCreationTime.setFont(new java.awt.Font("Tahoma", 1, 12));
        jLabelShowCreationTime.setText(" ");

        javax.swing.GroupLayout jPanelAnimationLayout = new javax.swing.GroupLayout(jPanelAnimation);
        jPanelAnimation.setLayout(jPanelAnimationLayout);
        jPanelAnimationLayout.setHorizontalGroup(
            jPanelAnimationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelAnimationLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelAnimationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanelAnimationLayout.createSequentialGroup()
                        .addGroup(jPanelAnimationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanelAnimationLayout.createSequentialGroup()
                                .addGap(23, 23, 23)
                                .addComponent(jPanelCPU, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(jPanelAnimationLayout.createSequentialGroup()
                                .addGap(40, 40, 40)
                                .addComponent(jLabelTime)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jLabelTimeCounter))
                            .addGroup(jPanelAnimationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                .addComponent(jLabelShowBurstTime, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(jLabelShowCreationTime, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 90, Short.MAX_VALUE)
                        .addComponent(jPanelReadyProcesses, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jProgressBarExecution, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        jPanelAnimationLayout.setVerticalGroup(
            jPanelAnimationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelAnimationLayout.createSequentialGroup()
                .addGroup(jPanelAnimationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanelAnimationLayout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(jPanelAnimationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabelTime)
                            .addComponent(jLabelTimeCounter))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanelCPU, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jProgressBarExecution, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabelShowBurstTime)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabelShowCreationTime))
                    .addComponent(jPanelReadyProcesses, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jPanelLegend.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Legenda", javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.TOP));
        jPanelLegend.setToolTipText("Legendas");

        jTextFieldLegendReady.setBackground(new java.awt.Color(255, 255, 255));
        jTextFieldLegendReady.setEditable(false);
        jTextFieldLegendReady.setFont(new java.awt.Font("Tahoma", 1, 11));
        jTextFieldLegendReady.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        jTextFieldLegendReady.setText("PRONTO");

        jTextFieldLegendExecuting.setBackground(new java.awt.Color(255, 51, 0));
        jTextFieldLegendExecuting.setEditable(false);
        jTextFieldLegendExecuting.setFont(new java.awt.Font("Tahoma", 1, 11));
        jTextFieldLegendExecuting.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        jTextFieldLegendExecuting.setText("EXECUTANDO");

        javax.swing.GroupLayout jPanelLegendLayout = new javax.swing.GroupLayout(jPanelLegend);
        jPanelLegend.setLayout(jPanelLegendLayout);
        jPanelLegendLayout.setHorizontalGroup(
            jPanelLegendLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelLegendLayout.createSequentialGroup()
                .addGap(131, 131, 131)
                .addComponent(jTextFieldLegendReady, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jTextFieldLegendExecuting, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(191, Short.MAX_VALUE))
        );
        jPanelLegendLayout.setVerticalGroup(
            jPanelLegendLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelLegendLayout.createSequentialGroup()
                .addGroup(jPanelLegendLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTextFieldLegendReady, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextFieldLegendExecuting, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jPanelProcesses.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Processos", javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.TOP));
        jPanelProcesses.setToolTipText("Painel para criar processos");

        jLabelBurstTime.setText("Tempo de Burst:");

        jTextFieldBurstTime.setToolTipText("Digite aqui o tempo de burst do processo a ser criado");

        jButtonCreateProcess.setText("Criar");
        jButtonCreateProcess.setToolTipText("Clique aqui para criar um processo");
        jButtonCreateProcess.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonCreateProcessActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelProcessesLayout = new javax.swing.GroupLayout(jPanelProcesses);
        jPanelProcesses.setLayout(jPanelProcessesLayout);
        jPanelProcessesLayout.setHorizontalGroup(
            jPanelProcessesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelProcessesLayout.createSequentialGroup()
                .addGap(57, 57, 57)
                .addComponent(jLabelBurstTime)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextFieldBurstTime, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(39, 39, 39)
                .addComponent(jButtonCreateProcess)
                .addContainerGap(236, Short.MAX_VALUE))
        );
        jPanelProcessesLayout.setVerticalGroup(
            jPanelProcessesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelProcessesLayout.createSequentialGroup()
                .addGroup(jPanelProcessesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(jPanelProcessesLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabelBurstTime)
                        .addComponent(jTextFieldBurstTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jButtonCreateProcess))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jButtonIntroduction.setToolTipText("Clique aqui para ver o algoritmo e um resumo teórico da política tratada");
        jButtonIntroduction.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonIntroduction.setLabel("Introdução");
        jButtonIntroduction.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonIntroductionActionPerformed(evt);
            }
        });

        jButtonStart.setText("Iniciar");
        jButtonStart.setToolTipText("Clique aqui para criar processos");
        jButtonStart.setEnabled(false);
        jButtonStart.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonStartActionPerformed(evt);
            }
        });

        jButtonAlgorithmSteps.setText("Passos do Algoritmo");
        jButtonAlgorithmSteps.setToolTipText("Clique aqui para escalonar e executar um processo da lista de prontos");
        jButtonAlgorithmSteps.setEnabled(false);
        jButtonAlgorithmSteps.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonAlgorithmSteps.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonAlgorithmStepsActionPerformed(evt);
            }
        });

        jButtonRestart.setText("Reiniciar");
        jButtonRestart.setToolTipText("Clique aqui para reiniciar o software");
        jButtonRestart.setEnabled(false);
        jButtonRestart.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonRestart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonRestartActionPerformed(evt);
            }
        });

        jButtonReport.setText("Relatório");
        jButtonReport.setToolTipText("Clique aqui para exibir o relatório de execução");
        jButtonReport.setEnabled(false);
        jButtonReport.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonReport.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonReportActionPerformed(evt);
            }
        });

        jButtonOkNextStep.setFont(new java.awt.Font("Tahoma", 1, 12));
        jButtonOkNextStep.setText("Clique aqui para próximo passo");
        jButtonOkNextStep.setToolTipText("Clique aqui para próximo passo");
        jButtonOkNextStep.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jPanelIntroduction, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jPanelAlgorithm, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addComponent(jPanelProcesses, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                    .addComponent(jPanelLegend, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                    .addComponent(jPanelAnimation, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 514, Short.MAX_VALUE)))))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(114, 114, 114)
                        .addComponent(jButtonIntroduction)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonStart)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonAlgorithmSteps)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonReport)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonRestart)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonOkNextStep)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanelIntroduction, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanelAlgorithm, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jPanelAnimation, javax.swing.GroupLayout.PREFERRED_SIZE, 211, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanelLegend, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanelProcesses, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonIntroduction)
                    .addComponent(jButtonStart)
                    .addComponent(jButtonAlgorithmSteps)
                    .addComponent(jButtonReport)
                    .addComponent(jButtonRestart)
                    .addComponent(jButtonOkNextStep))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonIntroductionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonIntroductionActionPerformed
        final String TEXT_BASE_INTRODUCTION = "\n" +
                                              "Informalmente, processo pode ser visto como um programa em execução, porém esta é uma idéia incompleta de como o sistema operacional\n" +
                                              "o trata. Atualmente, os computadores são capazes de realizar várias tarefas ao mesmo tempo. Ou seja, equanto executa um programa, um\n" +
                                              "computador pode, por exemplo, executar operações de leitura/escrita no disco ou executar outro programa. Em sistemas monoprocessados,\n" +
                                              "as tarefas não são executadas ao mesmo tempo, existe apenas a impressão delas estarem sendo executadas ao mesmo tempo, pois o processador\n" +
                                              "é capaz de realizar um tarefa por vez. Nesse sentido, existe o conceito de multiprogramação, que é a capacidade de armazenar o código de\n" +
                                              "muitos processos (programas) na memória simultaneamente para que eles possam ser executados. Assim, os programas podem acessar os recursos\n" +
                                              "do computador e serem executados em um tempo razoável tendo a sensação de multiprocessamento.\n\n" +
                                              "Nesse contexto, basicamente o gerenciador de processos garante que cada processo receba uma fatia de tempo suficiente para funcionar\n" +
                                              "corretamente e escalona (de acordo com a política implementada) os processos presentes na fila de prontos para que eles sejam executados.\n" +
                                              "A tarefa dessas políticas é escolher qual dos processos presentes na fila de prontos será o próximo a ser executado.\n" +
                                              "Utiliza-se como critério básico o objetivo de aumentar ao máximo o rendimento do sistema operacional, diminuido o tempo de resposta\n" +
                                              "(turnaround time = intervalo de tempo da submissão de um processo até o seu termino) ao usuário. Para conseguir um aumento de eficiência\n" +
                                              "no processador, busca-se reduzir o tempo médio de espera na fila de processos prontos. Tempo de espera é a soma dos períodos gastos por\n" +
                                              "um processo aguardando na fila de espera.\n\n" +
                                              "Existem duas categorias principais de políticas de escalonamento: preemptiva e não-preemptiva. Nas políticas não-preemptivas, quando um\n" +
                                              "processo assume o controle do processador, ele o mantém até terminar. Sua principal vantagem em relação às políticas preemptivas, é a\n" +
                                              "simplicidade. Sua desvantagem é a falta de resposta ao comportamento do sistema quando, por exemplo, um processo com alto tempo de\n" +
                                              "processamento detém controle do processador, todos os demais têm de esperar.\n" +
                                              "Nas políticas preemptivas, depois de certo tempo (devido, por exemplo, às diferentes prioridades dos processos), o sistema operacional\n" +
                                              "pode retomar o controle do processador.\n\n " +
                                              "*Este software educativo trata da política FIFO (First In First Out - primeiro a entrar primeiro a sair)\n" +
                                              "Também denominada como escalonamento FCFS (First Come First Served - primeiro a chegar primeiro servido), esta política é provavelmente a\n" +
                                              "mais simples de ser entendida e implementada. Esta política funciona da seguinte forma: quando um processado é iniciado, o sistema\n" +
                                              "operacional armazena seu bloco de controle de processo (atributos agrupados do processo) no fim de uma fila (fila de prontos). Quando o\n" +
                                              "processador estiver disponível, o sistema operacional passa o controle para o primeiro da fila. O processo utiliza o processador até\n" +
                                              "terminar e o sistema operacional passa o controle do processador para o processo seguinte. Em outras palavras, o primeiro processo que\n" +
                                              "chega usa o processador.\n\n" +
                                              "* VEJA O ALGORITMO ABAIXO";
        final String TEXT_BASE_ALGORITHM = "funcao fifo (referência de vetor<TAD_Processo> listaDeProntos) : TAD_Processo\n" +
                                           "inicio\n" +
                                           "    TAD_Processo processo;\n\n" +
                                           "    se (listaDeProntos não está vazia)\n" +
                                           "        processo := primeiro elemento do vetor listaDeProntos;\n" +
                                           "        remove primeiro elemento do vetor listaDeProntos;\n" +
                                           "        fifo := processo;\n" +
                                           "    Fim se\n" +
                                           "    senão\n" +
                                           "        Exibir mensagem \"Lista de processos prontos vazia!\";\n" +
                                           "        fifo := null;\n" +
                                           "    Fim senão\n"+
                                           "fim.";

        this.jTextAreaIntroduction.setText(TEXT_BASE_INTRODUCTION);
        this.jTextAreaAlgorithm.setText(TEXT_BASE_ALGORITHM);
        JOptionPane.showMessageDialog(null, "Após conferir o texto de introdução e o algoritmo tratado, \n" +
                "clique em 'Iniciar' para criar processos. \n", "DICA", JOptionPane.INFORMATION_MESSAGE);
        this.jButtonIntroduction.setEnabled(false);
        this.jButtonStart.setEnabled(true);
        this.jTextAreaIntroduction.setToolTipText("Introdução da política tratada");
        this.jTextAreaAlgorithm.setToolTipText("Algoritmo da política tratada");
    }//GEN-LAST:event_jButtonIntroductionActionPerformed

    private void jButtonStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonStartActionPerformed
        this.jPanelLegend.setVisible(true);
        this.jPanelProcesses.setVisible(true);
        this.jPanelReadyProcesses.setVisible(true);
        this.jLabelTimeCounter.setText("0");
        this.jLabelTime.setVisible(true);
        this.jLabelTimeCounter.setVisible(true);
        this.jPanelAnimation.setToolTipText("Aqui são exibidas animações gráficas da gerência de processador");
        JOptionPane.showMessageDialog(null, "Para criar um processo, digite seu tempo de burst e clique em 'Criar'.\n" +
                "OBSERVAÇÕES: 1) São permitidos somente valores inteiros entre " + MINIMUM + " e " + MAXIMUM + ";\n" +
                "                                2) Os processos criados vão para a lista de processos prontos;\n" +
                "                                3) Para escalonar e executar um processo da lista de prontos, clique em 'Passos do Algoritmo';\n" +
                "                                4) Passe o cursor do mouse sobre os processos prontos (Blocos Brancos) para ver seus tempos de burst e seus tempos de criação.", "DICA", JOptionPane.INFORMATION_MESSAGE);
        this.jButtonStart.setEnabled(false);
        this.jButtonRestart.setEnabled(true);
    }//GEN-LAST:event_jButtonStartActionPerformed

    private void jButtonCreateProcessActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCreateProcessActionPerformed
        if( (this.jTextFieldBurstTime.getText().equals("")) || ((Integer.parseInt(this.jTextFieldBurstTime.getText()) < MINIMUM)) || ((Integer.parseInt(this.jTextFieldBurstTime.getText()) > MAXIMUM)) ){
            JOptionPane.showMessageDialog(null, "Digite um número inteiro entre " + MINIMUM + " e " + MAXIMUM + " para o tempo de burst do processo.", "ERRO", JOptionPane.ERROR_MESSAGE);
        }
        else{
            if(this.processesList == null) {
                this.processesList = new Vector<Process>();
                this.reportBaseTemp = new Vector<Process>();
            }
            if(this.processesList.size() <= 20) {
                Process process = new Process();
                process.setLifeTime(Float.parseFloat(this.jTextFieldBurstTime.getText()));
                process.setId(this.processCounter);
                process.setState(0);
                if(st != null) {
                    this.timeCounter = st.getTimeCounter();
                    if(st.getJButtonOkNextStep().isVisible() == true) {
                        this.waitingTimeNecessary = st.getRemainingTimeToFinishRunning() + calculator.burstTimeSum(this.processesList);
                    }
                    else {
                        this.waitingTimeNecessary = this.calculator.burstTimeSum(this.processesList);
                    }
                }
                else {
                    this.waitingTimeNecessary = this.calculator.burstTimeSum(this.processesList);
                }
                process.setCreationTime((float)this.timeCounter);
                process.setWaitingTime(this.waitingTimeNecessary);
                process.setTurnAround(process.getWaitingTime() + process.getLifeTime());
                this.processesList.add(process);
                this.reportBaseTemp.add(process);
                this.paintProcessesList(this.processesList);
                this.processCounter++;
                JOptionPane.showMessageDialog(null, "Processo criado com sucesso!\n" +
                        "DICAS: 1) Para escalonar e executar um processo da lista de prontos, clique em 'Passos do Algoritmo';\n" +
                        "              2) Após a execução de um processo, clique em 'Relatório' para exibir informações estatísticas. ", "DICA", JOptionPane.INFORMATION_MESSAGE);
                
                if(this.st != null) {
                    if(!this.st.getJButtonOkNextStep().isVisible()) {
                        this.jButtonAlgorithmSteps.setEnabled(true);
                    }    
                }
                else {
                    this.jButtonAlgorithmSteps.setEnabled(true);
                }
            }
            else {
                JOptionPane.showMessageDialog(null, "A lista de processos prontos está cheia. \n" +
                            "DICA: Clique em 'Passos do Algoritmo' para escalonar e executar um processo da lista.", "ATENÇÃO", JOptionPane.WARNING_MESSAGE);
            }
        }
        this.jTextFieldBurstTime.setText("");        
}//GEN-LAST:event_jButtonCreateProcessActionPerformed

    private void jButtonAlgorithmStepsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAlgorithmStepsActionPerformed
        if(st != null) {
            this.reportBase = st.getReportBase();
            this.reportBaseTemp = st.getReportBaseTemp();
            this.timeCounter = st.getTimeCounter();
        }
        this.jProgressBarExecution.setValue(0);
        st = new AlgorithmStepsThread(this, this.jButtonAlgorithmSteps, this.jButtonReport, this.processesList, this.reportBase,
                                      this.reportBaseTemp, this.timeCounter, this.jPanelCPU, this.jProgressBarExecution,
                                      this.jLabelShowBurstTime, this.jLabelShowCreationTime, this.jLabelTimeCounter, this.jLabelCPU, this.jButtonOkNextStep);
        t = new Thread(st);
        t.start();
}//GEN-LAST:event_jButtonAlgorithmStepsActionPerformed

    private void jButtonRestartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonRestartActionPerformed
        this.jTextFieldBurstTime.setText("");
        this.timeCounter = 0;
        this.processCounter = 0;
        this.waitingTimeNecessary = 0;
        this.jLabelTime.setVisible(false);
        this.jLabelTimeCounter.setVisible(false);
        this.jProgressBarExecution.setVisible(false);
        this.jLabelShowBurstTime.setVisible(false);
        this.jLabelShowCreationTime.setVisible(false);
        this.jPanelReadyProcesses.removeAll();
        this.jPanelReadyProcesses.repaint();
        this.jPanelReadyProcesses.add(this.jLabelIncreaseOrientation);
        this.jPanelReadyProcesses.setVisible(false);
        this.jPanelCPU.removeAll();
        this.jPanelCPU.repaint();
        this.jPanelCPU.add(this.jLabelCPU);
        this.jPanelProcesses.setVisible(false);        
        this.jPanelLegend.setVisible(false);
        this.jButtonStart.setEnabled(true);
        this.jButtonAlgorithmSteps.setEnabled(false);
        this.jButtonReport.setEnabled(false);
        this.jButtonRestart.setEnabled(false);
        this.processesList = null;
        this.reportBaseTemp = null;
        this.reportBase = null;
        if(this.st != null) {
            this.st.getJButtonOkNextStep().setVisible(false);
            this.st = null;
        }
        if (this.t != null) {
            if (t.isAlive()) {
                t.stop();
            }    
        }
        System.gc();
    }//GEN-LAST:event_jButtonRestartActionPerformed

    private void jButtonReportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonReportActionPerformed
        if(st != null) {
            this.reportBase = st.getReportBase();
            this.reportBaseTemp = st.getReportBaseTemp();
        }

        String report = "";
        report += "* INFORMAÇÕES SOBRE OS PROCESSOS CRIADOS\n";

        for(int i = 0; i <= (this.reportBase.size() - 1); i++) {
            report += "P" + this.reportBase.elementAt(i).getId() + ": tempo de burst = " + (int)this.reportBase.elementAt(i).getLifeTime() + ";  tempo na criação = " + (int)this.reportBase.elementAt(i).getCreationTime() + ";\n";
        }
        
        for(int i = 0; i <= (this.reportBaseTemp.size() - 1); i++) {
            report += "P" + this.reportBaseTemp.elementAt(i).getId() + ": tempo de burst = " + (int)this.reportBaseTemp.elementAt(i).getLifeTime() + ";  tempo na criação = " + (int)this.reportBaseTemp.elementAt(i).getCreationTime() + ";\n";
        }
        
        report += "\n ** PROCESSOS EXECUTADOS\n";
        report += "\n* Tempos de espera\n";
        
        for(int i = 0; i <= (this.reportBase.size() - 1); i++) {
            report += "P" + this.reportBase.elementAt(i).getId() + " = " + (int)this.reportBase.elementAt(i).getWaitingTime() + ";  ";
            if ((i >0) && (i % 10 == 0)) {
                report += "\n";
            }
        }

        DecimalFormat df = new DecimalFormat("#0.00");

        float mediumWaintingTime = calculator.averageWaitingTime(this.reportBase);
        report += "\n\n* Tempo médio de espera\n";
        report += "(";
        for(int i = 0; i <= (this.reportBase.size() - 2); i++) {
            report += (int)this.reportBase.elementAt(i).getWaitingTime() + " + ";
            if((i >0) && (i % 21 == 0)) {
                report += "\n";
            }
        }
        report += (int)this.reportBase.lastElement().getWaitingTime() + ") / " + this.reportBase.size() + " = " + df.format(mediumWaintingTime);
        
        report += "\n\n* Tempos de retorno (turn around)\n";
        
        for(int i = 0; i <= (this.reportBase.size() - 1); i++) {
            report += "P" + this.reportBase.elementAt(i).getId() + " = " + (int)this.reportBase.elementAt(i).getTurnAround() + ";  ";
            if ((i >0) && (i % 10 == 0)) {
                report += "\n";
            }
        }
        
        float mediumTurnAround = calculator.averageTurnAround(this.reportBase);
        report += "\n\n* Tempo médio de retorno (turn around médio)\n";
        report += "(";
        for(int i = 0; i <= (this.reportBase.size() - 2); i++) {
            report += (int)this.reportBase.elementAt(i).getTurnAround() + " + ";
            if((i >0) && (i % 21 == 0)) {
                report += "\n";
            }
        }
        report += (int)this.reportBase.lastElement().getTurnAround() + ") / " + this.reportBase.size() + " = " + df.format(mediumTurnAround);
        
        JTextArea reportArea = new JTextArea(report);
        reportArea.setEditable(false);
        JScrollPane scroll = new JScrollPane(reportArea);
        Dimension preferredSize = new Dimension();
        preferredSize.setSize(625, 428);
        scroll.setPreferredSize(preferredSize);
        
        if(!this.reportBaseTemp.isEmpty()) {
            JOptionPane.showMessageDialog(null, scroll, "RELATÓRIO PARCIAL", JOptionPane.INFORMATION_MESSAGE);
        }
        else {
            JOptionPane.showMessageDialog(null, scroll, "RELATÓRIO FINAL", JOptionPane.INFORMATION_MESSAGE);
        }
    }//GEN-LAST:event_jButtonReportActionPerformed
    
    /*
     * This method paints the processes queue (Vector<Process> processesList) in 'jPanelReadyProcesses'.
     */ 
    public void paintProcessesList(Vector<Process> processesQueue) {
        int orientationAxisYSecMem = 40;
        
        this.jPanelReadyProcesses.removeAll();
        this.jPanelReadyProcesses.repaint();
        this.jPanelReadyProcesses.add(jLabelIncreaseOrientation);
        
        for(int i = 0; i <= (processesQueue.size() - 1); i++) {
            JTextField block = new JTextField();
            block.setBackground(new java.awt.Color(255, 255, 255));
            block.setForeground(new java.awt.Color(0, 0, 0));
            block.setHorizontalAlignment(javax.swing.JTextField.CENTER);
            block.setEditable(false);
            block.setText("P" + String.valueOf(processesQueue.elementAt(i).getId()));
            block.setToolTipText("Tempo de burst = " + String.valueOf((int)processesQueue.elementAt(i).getLifeTime()) + ";\n  Tempo na criação = " + String.valueOf((int)processesQueue.elementAt(i).getCreationTime()));
            this.jPanelReadyProcesses.add(block);
            
            if (i <= 6) {
                block.setBounds(15+(i*35), orientationAxisYSecMem, 30, 30);
            }
            else {
                if (i <= 13) {
                    block.setBounds(15+((i - 7)*35), orientationAxisYSecMem + 40, 30, 30);
                }
                else {
                    block.setBounds(15+((i - 14)*35), orientationAxisYSecMem + 80, 30, 30);
                }
            }
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonAlgorithmSteps;
    private javax.swing.JButton jButtonCreateProcess;
    private javax.swing.JButton jButtonIntroduction;
    private javax.swing.JButton jButtonOkNextStep;
    private javax.swing.JButton jButtonReport;
    private javax.swing.JButton jButtonRestart;
    private javax.swing.JButton jButtonStart;
    private javax.swing.JLabel jLabelBurstTime;
    private javax.swing.JLabel jLabelCPU;
    private javax.swing.JLabel jLabelIncreaseOrientation;
    private javax.swing.JLabel jLabelShowBurstTime;
    private javax.swing.JLabel jLabelShowCreationTime;
    private javax.swing.JLabel jLabelTime;
    private javax.swing.JLabel jLabelTimeCounter;
    private javax.swing.JPanel jPanelAlgorithm;
    private javax.swing.JPanel jPanelAnimation;
    private javax.swing.JPanel jPanelCPU;
    private javax.swing.JPanel jPanelIntroduction;
    private javax.swing.JPanel jPanelLegend;
    private javax.swing.JPanel jPanelProcesses;
    private javax.swing.JPanel jPanelReadyProcesses;
    private javax.swing.JProgressBar jProgressBarExecution;
    private javax.swing.JScrollPane jScrollPaneAlgorithm;
    private javax.swing.JScrollPane jScrollPaneIntroduction;
    private javax.swing.JTextArea jTextAreaAlgorithm;
    private javax.swing.JTextArea jTextAreaIntroduction;
    private javax.swing.JTextField jTextFieldBurstTime;
    private javax.swing.JTextField jTextFieldLegendExecuting;
    private javax.swing.JTextField jTextFieldLegendReady;
    // End of variables declaration//GEN-END:variables
    
}
